﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Rung.EBook.WebSiteAnalizer;
using Rung.EBook.Common.Model;
using Rung.Common;
using Rung.EBook.WebSiteAnalizer.Analizer;

namespace Rung.EBook.UI.Forms
{
    public partial class LoadAnalizerForm : Form
    {
        // 在窗体提示框中显示值
        ToolTip mToopTip;
        BackgroundWorker mWorker;
        private WriteInfo mWriteInfo;
        private AppendInfo mAppendInfo;
        BookBase mBookBM;// 本窗体选择的书籍
        internal List<AnalizerBase> mAnalizers;// 解析器工厂返回的所有解析器
        Dictionary<string, string> mBooks;// 本解析器获取的书籍列表
        internal AnalizerBase mAnalizerForUse;// 由于解析器的章节URL中存在书籍 Id 通配符，在选定书籍时才能确定，所以定义的解析器不能直接投入使用，该对象则为传递给父窗体直接使用的解析器

        private LoadAnalizerForm()
        {
            InitializeComponent();

            this.mBookBM = new BookBase();
            this.mBooks = new Dictionary<string, string>();

            mToopTip = new ToolTip();
            mToopTip.InitialDelay = 0;
            mToopTip.ShowAlways = true;
            mToopTip.ToolTipTitle = "完整信息";
            mToopTip.UseAnimation = false;
            mToopTip.UseFading = false;
        }

        internal LoadAnalizerForm(WriteInfo writeInfo, AppendInfo appendInfo, LoadAnalizerFormClose e)
            : this()
        {
            this.mWriteInfo = writeInfo;
            this.mAppendInfo = appendInfo;

            this.OnLoadAnalizerFormClose += e;
        }

        private void LoadAnalizerForm_Load(object sender, EventArgs e)
        {
            mAnalizers = Rung.EBook.WebSiteAnalizer.Analizer.AnalizerFactory.GetAnalizers();

            //ddlAnalizer.DataBindings.Add("Value", this.mAnalizers.ToArray(), "Name");
            this.ddlAnalizerBind();
        }

        // 下拉框选值事件
        private void ddlAnalizer_SelectedIndexChanged(object sender, EventArgs e)
        {
            AnalizerBase analizer = ddlAnalizer.SelectedItem as AnalizerBase;

            if (analizer == null)
            {
                this.mWriteInfo("请先选择解释器。", InfoType.Errer);
                return;
            }

            #region 填充解析器参数文本框
            //txbBooksUrl.Text = analizer.BooksUrl;
            //txbBookRegex.Text = analizer.BookRegex;
            //txbChaptersUrl.Text = analizer.ChaptersUrl;
            //txbChapterRegex.Text = analizer.ChapterRegex;
            //txbContentBaseUrl.Text = analizer.ContentBaseUrl;
            //txbContentRegex.Text = analizer.ContentRegex;

            //mToopTip.SetToolTip(txbBooksUrl, txbBooksUrl.Text);
            //mToopTip.SetToolTip(txbBookRegex, txbBookRegex.Text);
            //mToopTip.SetToolTip(txbChaptersUrl, txbChaptersUrl.Text);
            //mToopTip.SetToolTip(txbChapterRegex, txbChapterRegex.Text);
            //mToopTip.SetToolTip(txbContentBaseUrl, txbContentBaseUrl.Text);
            //mToopTip.SetToolTip(txbContentRegex, txbContentRegex.Text);
            this.AnalizerForUseToUI(analizer);
            #endregion

            if (string.IsNullOrEmpty(analizer.BooksUrl))
            {
                // 生成可以直接使用的解析器
                this.mAnalizerForUse = AnalizerBase.GetAnalizerForUse(analizer, "", "");
            }
            else
            {
                // 也放进去吧
                this.mAnalizerForUse = AnalizerBase.GetAnalizerForUse(analizer, "", "");

                try
                {
                    this.mWriteInfo("初始化下载进程...", InfoType.Process);
                    GetBookAsync(analizer);
                }
                catch (Exception ex)
                {
                    this.mWriteInfo("获取书籍列表失败：" + ex.Message, InfoType.Errer);
                    return;
                }
            }
        }

        // 异步获取书籍
        private void GetBookAsync(AnalizerBase analizer)
        {

            mWorker = new BackgroundWorker();
            mWorker.WorkerSupportsCancellation = true;
            mWorker.DoWork += new DoWorkEventHandler(GetBooks_DoWork);
            mWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(GetBooks_RunWorkerCompleted);
            this.mAppendInfo("完成。");

            mWorker.RunWorkerAsync(analizer);
        }

        #region BackgroundWorker: GetBooks
        void GetBooks_DoWork(object sender, DoWorkEventArgs e)
        {
            AnalizerBase aBM = e.Argument as AnalizerBase;

            this.mWriteInfo("开始获取书籍列表...", InfoType.Process);
            try
            {
                aBM.FillBooksList(this.mBooks);
            }
            catch (Exception ex)
            {
                e.Result = ex;
            }
        }

        void GetBooks_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                this.mWriteInfo("线程错误1：" + e.Error.Message, InfoType.Warning);
                //return;
            }
            if (e.Result is Exception)
            {
                Exception ex = e.Result as Exception;
                this.mWriteInfo("线程错误2：" + ex.Message, InfoType.Warning);
                //return;
            }
            if (e.Cancelled == true)
            {
                this.mWriteInfo("获取章节列表进程取消。", InfoType.Warning);
                //return;
            }

            this.mAppendInfo("成功");

            try
            {
                BindingSource bs = new BindingSource();
                bs.DataSource = this.mBooks;
                this.clbBooks.DataSource = bs;
                this.clbBooks.ValueMember = "Key";
                this.clbBooks.DisplayMember = "Value";
                isRecursived = false;
            }
            catch (Exception ex)
            {
                this.mWriteInfo("线程错误3：" + ex.Message, InfoType.Warning);
            }

            //mWorker.Dispose();
        }
        #endregion

        // 确定按钮事件
        private void btnSubmit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private LoadAnalizerFormClose OnLoadAnalizerFormClose;

        // 窗口关闭，向父窗口传值
        private void LoadAnalizerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (this.OnLoadAnalizerFormClose != null && this.mAnalizerForUse != null)
                this.OnLoadAnalizerFormClose(this.mAnalizerForUse);
        }

        bool isRecursived = false;
        // 书籍列表选择事件
        private void clbBooks_SelectedIndexChanged(object sender, EventArgs e)
        {
            int iSeleced = clbBooks.SelectedIndex;

            if (iSeleced >= 0 && isRecursived == false)
            {
                // 关闭方法入口（防止下面取消选中时引起的递归死循环）
                isRecursived = true;
                #region 取消选中所有项
                clbBooks.ClearSelected();// 此方法和 SelectedIndexChanged 会形成死循环，所以必须用变量  判断如果是递归进入的方法，应该退出。 
                foreach (int i in clbBooks.CheckedIndices) clbBooks.SetItemChecked(i, false);
                #endregion
                #region 选中第 iSeleced 项
                clbBooks.SelectedIndex = iSeleced;
                clbBooks.SetItemChecked(iSeleced, false);
                #endregion

                KeyValuePair<string, string> pair = new KeyValuePair<string, string>();
                try
                {
                    pair = (KeyValuePair<string, string>)clbBooks.SelectedItem;
                    //if (pair.Value == null)
                    //{
                    //    pair = new KeyValuePair<string, string>(this.mAnalizers[0].Name, this.mAnalizers[0].BookName);
                    //}

                    btnSubmit.Enabled = true;
                }
                catch
                {
                    btnSubmit.Enabled = false;
                    return;
                }

                AnalizerBase analizer = this.ddlAnalizer.SelectedItem as AnalizerBase;

                // 生成可以直接使用的解析器
                this.mAnalizerForUse = AnalizerBase.GetAnalizerForUse(analizer, pair.Key, pair.Value);

                // 显示选中的书名
                this.txbChaptersUrl.Text = this.mAnalizerForUse.ChaptersUrl;
                this.txbChapterRegex.Text = this.mAnalizerForUse.ChapterRegex;
                this.txbContentBaseUrl.Text = this.mAnalizerForUse.ContentBaseUrl;
                lbBookName.Text = (string.IsNullOrEmpty(this.mAnalizerForUse.BookNamePrefix)) ? pair.Value : this.mAnalizerForUse.BookNamePrefix + "-" + pair.Value;
                mToopTip.SetToolTip(lbBookName, this.txbChaptersUrl.Text);

                isRecursived = false;
            }
        }

        // 【保存】
        private void btnSave_Click(object sender, EventArgs e)
        {
            AnalizerFactory.SaveAnalizers(this.mAnalizers);
            MessageBox.Show("保存成功。");
        }

        // 【编辑】
        private void btnEdit_Click(object sender, EventArgs e)
        {
            LoadAnalizerAddForm form = new LoadAnalizerAddForm(this);
            // 关闭窗口后，刷新书籍列表
            form.FormClosed += new FormClosedEventHandler((s, args) =>
            {
                this.AnalizerForUseToUI(this.mAnalizerForUse);
                this.GetBookAsync(this.mAnalizerForUse);
            });

            form.Show(this);
        }

        // 【删除】
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("确认删除该解释器？", "警告", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                AnalizerBase currA = ddlAnalizer.SelectedItem as AnalizerBase;

                if (currA != null)
                {
                    for (int i = 0; i < this.mAnalizers.Count; i++)
                    {
                        if (this.mAnalizers[i].Name == currA.Name)
                        {
                            this.mAnalizers.RemoveAt(i);
                            MessageBox.Show("删除成功。\r\n只有点击【保存】按钮后才会持久化到本地用户文件中。");
                            this.ddlAnalizerBind();
                            return;
                        }
                    }
                    MessageBox.Show("没有找到该项！");
                }
            }
        }

        // 重新对 ddlAnalizer 控件进行数据绑定。
        internal void ddlAnalizerBind()
        {
            ddlAnalizer.DataSource = mAnalizers.ToArray();
            ddlAnalizer.DisplayMember = "Name";
            //((CurrencyManager)this.BindingContext[this.mAnalizers]).Refresh();
        }

        // 将指定的解析器反映到本窗体上。
        private void AnalizerForUseToUI(AnalizerBase a)
        {
            txbBooksUrl.Text = a.BooksUrl;
            txbBookRegex.Text = a.BookRegex;
            txbChaptersUrl.Text = a.ChaptersUrl;
            txbChapterRegex.Text = a.ChapterRegex;
            txbContentBaseUrl.Text = a.ContentBaseUrl;
            txbContentRegex.Text = a.ContentRegex;

            mToopTip.SetToolTip(txbBooksUrl, txbBooksUrl.Text);
            mToopTip.SetToolTip(txbBookRegex, txbBookRegex.Text);
            mToopTip.SetToolTip(txbChaptersUrl, txbChaptersUrl.Text);
            mToopTip.SetToolTip(txbChapterRegex, txbChapterRegex.Text);
            mToopTip.SetToolTip(txbContentBaseUrl, txbContentBaseUrl.Text);
            mToopTip.SetToolTip(txbContentRegex, txbContentRegex.Text);
        }
    }

    public delegate void LoadAnalizerFormClose(AnalizerBase analizer);
}
